package com.borealis.common.utils.lock;

import com.google.common.collect.Maps;

import java.util.concurrent.ConcurrentMap;

/**
 * 内存锁
 *
 * @author yaoweixin
 * @date 2018/10/15
 */
public class MemoryLock extends AbstractIdLock {

  ConcurrentMap<String, Long> threadLock = Maps.newConcurrentMap();

  @Override
  protected Long getThreadId() {
    // get id from redis to support multi-instance
    // current just use threadId;
    return Thread.currentThread().getId();
  }

  @Override
  protected void lock(String res, Long threadId) {
    // memory version
    if (threadId.equals(threadLock.get(res))) {
      return;
    }
    while (true) {
      if (threadLock.putIfAbsent(res, threadId) == null) {
        return;
      }
      try {
        Thread.sleep(1);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    }
  }

  @Override
  protected boolean returnLock(String res, Long threadId) {
    // memory version
    if (threadId.equals(threadLock.get(res))) {
      return true;
    }
    return threadLock.putIfAbsent(res, threadId) == null;
  }

  @Override
  protected void unlock(String res, Long threadId) {
    assert threadId.equals(threadLock.get(res));
    threadLock.remove(res);
  }
}
